package com.example.logindemo.service.impl;

import com.example.logindemo.entity.Review;
import com.example.logindemo.entity.ReviewImage;
import com.example.logindemo.entity.RunOrder;
import com.example.logindemo.repository.ReviewImageRepository;
import com.example.logindemo.repository.ReviewRepository;
import com.example.logindemo.repository.RunOrderRepository;
import com.example.logindemo.service.ReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
public class ReviewServiceImpl implements ReviewService {

    @Autowired
    private ReviewRepository reviewRepository;
    
    @Autowired
    private ReviewImageRepository reviewImageRepository;
    
    @Autowired
    private RunOrderRepository runOrderRepository;
    
    @Value("${file.upload-dir:uploads}")
    private String uploadDir;

    @Override
    @Transactional
    @CacheEvict(value = "reviews", allEntries = true)
    public Review createReview(Review review) {
        review.setCreateTime(new Date());
        review.setUpdateTime(new Date());
        review.setEdited(false);
        return reviewRepository.save(review);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "#id")
    public Optional<Review> getReviewById(Integer id) {
        return reviewRepository.findById(id);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'runOrderId:' + #runOrderId")
    public Optional<Review> getReviewByRunOrderId(String runOrderId) {
        return reviewRepository.findByRunOrderId(runOrderId);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'userId:' + #userId")
    public List<Review> getReviewsByUserId(Integer userId) {
        return reviewRepository.findByUserId(userId);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'all'")
    public List<Review> getAllReviews() {
        return reviewRepository.findAll();
    }

    @Override
    @Transactional
    @CacheEvict(value = "reviews", allEntries = true)
    public Review updateReview(Review review) {
        review.setUpdateTime(new Date());
        review.setEdited(true);
        return reviewRepository.save(review);
    }

    @Override
    @Transactional
    @CacheEvict(value = "reviews", allEntries = true)
    public void deleteReview(Integer id) {
        // 先删除相关的评价图片
        reviewImageRepository.deleteByReviewId(id);
        // 再删除评价
        reviewRepository.deleteById(id);
    }

    @Override
    @Transactional
    @CacheEvict(value = {"reviews", "runOrders"}, allEntries = true)
    public Map<String, Object> submitReview(String runOrderId, Integer rating, String content, String tags,
                                         List<MultipartFile> images, Integer userId, String userName) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 1. 验证订单是否存在且已完成
            Optional<RunOrder> runOrderOpt = runOrderRepository.findByRunOrderId(runOrderId);
            if (!runOrderOpt.isPresent()) {
                response.put("success", false);
                response.put("message", "跑单不存在");
                return response;
            }
            
            RunOrder runOrder = runOrderOpt.get();
            if (!"completed".equals(runOrder.getStatus())) {
                response.put("success", false);
                response.put("message", "只有已完成的订单才能评价");
                return response;
            }
            
            // 2. 检查是否已经评价过
            if (reviewRepository.existsByRunOrderId(runOrderId)) {
                response.put("success", false);
                response.put("message", "该订单已经评价过了");
                return response;
            }
            
            // 3. 创建评价
            Review review = new Review();
            review.setRunOrderId(runOrderId);
            review.setRating(rating);
            review.setContent(content);
            review.setTags(tags);
            review.setUserId(userId);
            review.setUserName(userName);
            review.setUserLevel("普通会员");
            review.setEdited(false);
            
            // 4. 保存评价
            Review savedReview = reviewRepository.save(review);
            
            // 5. 处理图片
            if (images != null && !images.isEmpty()) {
                List<ReviewImage> reviewImages = new ArrayList<>();
                for (MultipartFile image : images) {
                    if (!image.isEmpty() && image.getSize() <= 5 * 1024 * 1024) { // 5MB限制
                        String fileName = saveImage(image);
                        ReviewImage reviewImage = new ReviewImage();
                        reviewImage.setReviewId(savedReview.getId());
                        reviewImage.setUrl("/uploads/" + fileName);
                        reviewImage.setFileName(image.getOriginalFilename());
                        reviewImage.setSize(image.getSize());
                        reviewImages.add(reviewImage);
                    }
                }
                if (!reviewImages.isEmpty()) {
                    reviewImageRepository.saveAll(reviewImages);
                    savedReview.setImages(reviewImages);
                }
            }
            
            // 6. 更新订单评价状态
            runOrder.setReviewStatus("reviewed");
            runOrderRepository.save(runOrder);
            
            response.put("success", true);
            response.put("message", "评价提交成功");
            response.put("review", savedReview);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "评价提交失败: " + e.getMessage());
        }
        
        return response;
    }

    @Override
    @Transactional
    @CacheEvict(value = "reviews", allEntries = true)
    public Map<String, Object> editReview(Integer reviewId, Integer rating, String content, String tags,
                                       List<MultipartFile> images, List<String> removeImageIds) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 1. 查找评价
            Optional<Review> reviewOpt = reviewRepository.findById(reviewId);
            if (!reviewOpt.isPresent()) {
                response.put("success", false);
                response.put("message", "评价不存在");
                return response;
            }
            
            Review review = reviewOpt.get();
            
            // 2. 更新评价信息
            review.setRating(rating);
            review.setContent(content);
            review.setTags(tags);
            review.setUpdateTime(new Date());
            review.setEdited(true);
            
            // 3. 删除指定的图片
            if (removeImageIds != null && !removeImageIds.isEmpty()) {
                for (String imageId : removeImageIds) {
                    try {
                        Integer id = Integer.parseInt(imageId);
                        reviewImageRepository.deleteById(id);
                    } catch (NumberFormatException e) {
                        // 忽略无效的图片ID
                    }
                }
            }
            
            // 4. 添加新图片
            if (images != null && !images.isEmpty()) {
                // 获取现有的图片数量
                long existingCount = reviewImageRepository.countByReviewId(reviewId);
                int remainingSlots = 5 - (int) existingCount; // 假设最多5张图片
                
                if (remainingSlots > 0) {
                    List<ReviewImage> newImages = new ArrayList<>();
                    int count = 0;
                    
                    for (MultipartFile image : images) {
                        if (count >= remainingSlots) break;
                        
                        if (!image.isEmpty() && image.getSize() <= 5 * 1024 * 1024) { // 5MB限制
                            String fileName = saveImage(image);
                            ReviewImage reviewImage = new ReviewImage();
                            reviewImage.setReviewId(reviewId);
                            reviewImage.setUrl("/uploads/" + fileName);
                            reviewImage.setFileName(image.getOriginalFilename());
                            reviewImage.setSize(image.getSize());
                            newImages.add(reviewImage);
                            count++;
                        }
                    }
                    
                    if (!newImages.isEmpty()) {
                        reviewImageRepository.saveAll(newImages);
                    }
                }
            }
            
            // 5. 保存更新后的评价
            Review updatedReview = reviewRepository.save(review);
            
            // 6. 重新加载评价，包含最新的图片列表
            updatedReview.setImages(reviewImageRepository.findByReviewId(reviewId));
            
            response.put("success", true);
            response.put("message", "评价更新成功");
            response.put("review", updatedReview);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "评价更新失败: " + e.getMessage());
        }
        
        return response;
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'latest:10'")
    public List<Review> getLatestReviews(int limit) {
        return reviewRepository.findTop10ByOrderByCreateTimeDesc();
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'ratingRange:' + #minRating + '-' + #maxRating")
    public List<Review> getReviewsByRatingBetween(Integer minRating, Integer maxRating) {
        return reviewRepository.findByRatingBetween(minRating, maxRating);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviewStats", key = "'averageRating'")
    public Double getAverageRating() {
        return reviewRepository.getAverageRating();
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviewStats", key = "'total'")
    public long getTotalReviews() {
        return reviewRepository.count();
    }
    
    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "reviews", key = "'isReviewed:' + #runOrderId")
    public boolean isOrderReviewed(String runOrderId) {
        return reviewRepository.existsByRunOrderId(runOrderId);
    }
    
    // 保存图片到本地文件系统
    private String saveImage(MultipartFile file) throws IOException {
        // 确保上传目录存在
        File uploadDirFile = new File(uploadDir);
        if (!uploadDirFile.exists()) {
            uploadDirFile.mkdirs();
        }
        
        // 生成唯一文件名
        String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
        File destination = new File(uploadDirFile, fileName);
        
        // 保存文件
        file.transferTo(destination);
        
        return fileName;
    }
}